package com.demon.activitychange.xposed;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.widget.Checkable;
import android.widget.EditText;

import com.alibaba.fastjson.JSON;
import com.demon.activitychange.net.impl.MD5Util;
import com.demon.activitychange.persist.impl.FilePersist;
import com.demon.activitychange.util.FileUtil;
import com.demon.activitychange.util.JSONObjectPack;
import com.demon.activitychange.util.TraceUtil;
import com.demon.activitychange.xposed.HookMain.DyOperEnum;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;

public class HookLiteHandler {

    private Handler mainHandler = new Handler(Looper.getMainLooper());
    private Activity mainActivityObj, dYLoginActivityObj, updatePasswordActivityObj;
    private Class DYLoginActivityCls, UpdatePasswordActivityCls, PhoneBeanCls;
    private volatile DyOperEnum mOperEnum = DyOperEnum.unknown;
    private String mPhone, mPrefix, mPass, mCode;
    private JSONObject mLoginInfo = new JSONObject();
    private volatile boolean isPassLoginSuccess = true;

    void hook(ClassLoader appClassLoader, Context context) {
        try {
            mPrefix = (String) FilePersist.newInstance(HookMain.PACKAGE_ID_LITE).readData("device", "8612");
            mPhone = (String) FilePersist.newInstance(HookMain.PACKAGE_ID_LITE).readData("phone", "18566506650");
            // hookGorgon(appClassLoader, context);
            hookDevice(appClassLoader, context);
            hookDeviceId(appClassLoader, context);
            hookDialog(appClassLoader, context);
            hookNet(appClassLoader, context);
            hookLogin(appClassLoader, context);
        } catch (Exception e) {
            TraceUtil.xe("" + e.getMessage());
        }
    }

    private void hookGorgon(final ClassLoader classLoader, final Context context) {
        TraceUtil.e("hookGorgon");
        Class SSABACls = XposedHelpers.findClass("com.ss.a.b.a", classLoader);
        XposedHelpers.findAndHookMethod(SSABACls, "a", String.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("decode param0 = " + param.args[0]);
                TraceUtil.e("decode result = " + Arrays.toString((byte[]) param.getResult()));
            }
        });

        Class CESACls = XposedHelpers.findClass("com.ss.sys.ces.a", classLoader);
        XposedHelpers.findAndHookMethod(CESACls, "leviathan", int.class, int.class, byte[].class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("leviathan param0 = " + param.args[0] + ", param1 = " + param.args[1] + ", param2 = " + Arrays.toString((byte[]) param.args[2]));
                TraceUtil.e("leviathan result = " + Arrays.toString((byte[]) param.getResult()));
            }
        });

        XposedHelpers.findAndHookMethod(SSABACls, "a", byte[].class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("encode param0 = " + Arrays.toString((byte[]) param.args[0]));
                TraceUtil.e("encode result = " + param.getResult());
            }
        });


        Class CesGgTtCls = XposedHelpers.findClass("com.ss.sys.ces.gg.tt", classLoader);
        Class HttpECls = XposedHelpers.findClass("com.bytedance.frameworks.baselib.network.http.e", classLoader);
        XposedHelpers.findAndHookMethod(CesGgTtCls, "init_gorgon", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("init_gorgon");
                Object xGorgonObj = XposedHelpers.getStaticObjectField(HttpECls, "k");
                if (xGorgonObj == null) {
                    TraceUtil.e("xGorgonObj is null !");
                    return;
                }

                Class xGorgonCls = xGorgonObj.getClass();
                TraceUtil.e("xGorgonObj " + xGorgonCls.getName());
                XposedHelpers.findAndHookMethod(xGorgonCls, "a", String.class, Map.class, new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        super.afterHookedMethod(param);
                        TraceUtil.e("xGorgonObj param0 = " + param.args[0]);
                        TraceUtil.e("xGorgonObj param1 = " + param.args[1]);
                        TraceUtil.e("xGorgonObj result = " + param.getResult());
                    }
                });
            }
        });
    }

    private void hookDevice(final ClassLoader classLoader, final Context context) {
        TraceUtil.e("hookDevice");
        Class TelephonyManagerCls = XposedHelpers.findClass("android.telephony.TelephonyManager", classLoader);
        XposedHelpers.findAndHookMethod(TelephonyManagerCls, "getDeviceId", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                String deviceId = (String) param.getResult();
                String nDeviceId = mPrefix + mPhone;
                // TraceUtil.e("deviceId: prev = " + deviceId + ", nDeviceId = " + nDeviceId);
                param.setResult(nDeviceId);
            }
        });
        XposedHelpers.findAndHookMethod(TelephonyManagerCls, "getDeviceId", int.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                String deviceId = (String) param.getResult();
                String nDeviceId = mPrefix + mPhone;
                param.setResult(nDeviceId);
            }
        });
        Class WifiInfoCls = XposedHelpers.findClass("android.net.wifi.WifiInfo", classLoader);
        XposedHelpers.findAndHookMethod(WifiInfoCls, "getMacAddress", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                String mac = (String) param.getResult();
                String nMac = MD5Util.GetMD5Code(mPrefix + mPhone).substring(20);
                nMac = nMac.replaceAll("(.{2})", "$1:").substring(0, 17);
                // TraceUtil.e("mac: prev = " + mac + ", new = " + nMac);
                param.setResult(nMac);
            }
        });
        Class SettingsCls = XposedHelpers.findClass("android.provider.Settings.Secure", classLoader);
        XposedHelpers.findAndHookMethod(SettingsCls, "getString", ContentResolver.class, String.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                if ("android_id".equals(param.args[1])) {
                    String androidId = (String) param.getResult();
                    String nAndroidId = MD5Util.GetMD5Code(mPrefix + mPhone).substring(0, 16);
                    // TraceUtil.e("androidId: prev = " + androidId + ", new = " + nAndroidId);
                    param.setResult(nAndroidId);
                }
            }
        });
    }

    private void hookDeviceId(final ClassLoader classLoader, final Context context) {
        TraceUtil.e("hookDeviceId");
        // device_register接口，post 数据不加密
//        Class AppLogCls = XposedHelpers.findClass("com.ss.android.common.applog.AppLog", classLoader);
//        XposedHelpers.findAndHookMethod(AppLogCls, "getLogEncryptSwitch", new XC_MethodHook() {
//            @Override
//            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//                super.afterHookedMethod(param);
//                param.setResult(false);
//            }
//        });

        Class DeviceRegisterThreadCls = XposedHelpers.findClass("com.ss.android.deviceregister.b.c.a", classLoader);
        XposedHelpers.findAndHookMethod(DeviceRegisterThreadCls, "a", String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);
                String postParam = (String) param.args[0];
                // TraceUtil.e("post param: " + postParam);
                JSONObject postObj = new JSONObject(postParam);
                JSONObject obj = postObj.getJSONObject("header");
                if (obj != null) {
                    obj.put("apk_first_install_time", 0);
                }

                String nPostParam = postObj.toString();
                // TraceUtil.e("post nParam: " + nPostParam);
                param.args[0] = nPostParam;
            }
        });
    }

    private void hookDialog(final ClassLoader classLoader, final Context context) {
        TraceUtil.e("hookDialog");
        Class RemindCls = XposedHelpers.findClass("com.ss.android.ugc.aweme.main.bz", classLoader);
        XposedHelpers.findAndHookMethod(RemindCls, "show", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("remind dilaog is show");
                Dialog dialog = (Dialog) param.thisObject;
                int confirmId = dialog.getContext().getResources().getIdentifier("s0", "id", dialog.getContext().getPackageName());
                dialog.findViewById(confirmId).performClick();
            }
        });

        Class RedpacketCls = XposedHelpers.findClass("com.ss.android.ugc.aweme.ug.luckycat.depend.ui.c", classLoader);
        XposedHelpers.findAndHookMethod(RedpacketCls, "show", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("redpacket dilaog is show");
                XposedHelpers.callMethod(param.thisObject, "dismiss");
            }
        });
    }

    private void hookNet(final ClassLoader classLoader, final Context context) {
        TraceUtil.e("hookNet");

        // 获取网络请求的header、cookie
        Class UrlRequestBuilderImplCls = XposedHelpers.findClass("com.ttnet.org.chromium.net.impl.UrlRequestBuilderImpl", classLoader);
        XposedHelpers.findAndHookMethod(UrlRequestBuilderImplCls, "build", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                Object obj = param.thisObject;
                String url = (String) XposedHelpers.getObjectField(obj, "mUrl");
                Object headers = XposedHelpers.getObjectField(obj, "mRequestHeaders");
//                if (!TextUtils.isEmpty(url) &&
//                        (url.contains("?is_after_login") || url.contains("/passport/mobile/send_code") || url.contains("/passport/mobile/login") || url.contains("/passport/mobile/sms_login"))) {
//                    TraceUtil.e("req url = " + url + ", header = " + JSON.toJSONString(headers));
//                    // StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
//                    // TraceUtil.e("req stacks: " + Arrays.toString(stacks));
//                }

                if (!TextUtils.isEmpty(url) && (url.contains("?is_after_login"))) {
                    String headerStr = JSON.toJSONString(headers);
                    url = PayUtils.getMidText(url, "is_after_login=", "");
                    url = url.substring(1);
                    TraceUtil.e("req url = " + url);
                    TraceUtil.e("req header = " + headerStr);
                    mLoginInfo = new JSONObjectPack()
                            .putValue("phone", mPhone)
                            .putValue("urlParam", url)
                            .putValue("header", headerStr)
                            .getJSONObject();

                    if (mOperEnum == DyOperEnum.login) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                TraceUtil.e("****** dy passport login end ******");
                                sendResult(mainActivityObj, DyOperEnum.login.getResult(), 0, mLoginInfo, "");
                                clearExitApp(mainActivityObj);
                            }
                        });
                    } else if (mOperEnum == DyOperEnum.loginVerify) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                TraceUtil.e("****** dy passport login verify end ******");
                                sendResult(mainActivityObj, DyOperEnum.loginVerify.getResult(), 0, mLoginInfo, "");
                                clearExitApp(mainActivityObj);
                            }
                        });
                    } else if (mOperEnum == DyOperEnum.smsLogin) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                TraceUtil.e("****** dy passport sms login end ******");
                                sendResult(mainActivityObj, DyOperEnum.smsLogin.getResult(), 0, mLoginInfo, "");
                                clearExitApp(mainActivityObj);
                            }
                        });
                    }
                }

                // 监听device_register接口的请求
                if (!TextUtils.isEmpty(url) && (url.contains("/device_register"))) {
                    TraceUtil.e("req url = " + url);
                    if (mOperEnum == DyOperEnum.login) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                loginPage();
                            }
                        });
                    } else if (mOperEnum == DyOperEnum.sendCode) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                sendCodePage();
                            }
                        });
                    }
                }

//                if (!TextUtils.isEmpty(url) && (url.contains("/aweme/v2/feed") || url.contains("/aweme/v2/comment/list"))) {
//                    TraceUtil.e("req url = " + url);
//                     StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
//                     TraceUtil.e("req stack: " + Arrays.toString(stacks));
//                }

            }
        });

        // 获取网络请求的结果
        Class SsHttpCallCls = XposedHelpers.findClass("com.bytedance.retrofit2.SsHttpCall", classLoader);
        XposedBridge.hookAllMethods(SsHttpCallCls, "getResponseWithInterceptorChain", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                Object ssResponse = param.getResult();
                if (ssResponse == null) {
                    TraceUtil.e("res is null");
                    return;
                }
                Object rawResponse = XposedHelpers.callMethod(ssResponse, "raw");
                String url = (String) XposedHelpers.getObjectField(rawResponse, "a");
                if (!TextUtils.isEmpty(url) && (url.contains("/device_register") || url.contains("?is_after_login") ||
                        url.contains("/passport/mobile/send_code") || url.contains("/passport/mobile/login") || url.contains("/passport/mobile/sms_login") ||
                        url.contains("/passport/password/check") || url.contains("/passport/password/change"))) {
                    // || url.contains("/aweme/v2/feed") || url.contains("/aweme/v2/comment/list")
                    int status = XposedHelpers.getIntField(rawResponse, "e");
                    byte[] bodyByte = (byte[]) XposedHelpers.getObjectField(XposedHelpers.getObjectField(rawResponse, "c"), "bytes");
                    String body = new String(bodyByte);
                    TraceUtil.e("res success, status = " + status + ", url = " + url + ", body = " + body);

                    if (url.contains("/passport/mobile/send_code") && (mOperEnum == DyOperEnum.sendCode || mOperEnum == DyOperEnum.login)) {
                        JSONObject obj = new JSONObject(body);
                        String message = obj.optString("message");
                        TraceUtil.e("****** dy passport send code end ******");
                        if ("success".equals(message)) {
                            if (mOperEnum == DyOperEnum.login) {
                                sendResult(mainActivityObj, DyOperEnum.login.getResult(), 101, null, "请输入抖音发送的验证码");
                            } else if (mOperEnum == DyOperEnum.sendCode) {
                                sendResult(mainActivityObj, DyOperEnum.sendCode.getResult(), 0, null, "");
                            }
                        } else {
                            JSONObject data = obj.optJSONObject("data");
                            final int errCode = data.optInt("error_code");
                            final String msg = "error_code = " + data.optString("error_code") + ", description = " + data.optString("description");
                            mainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    if (mOperEnum == DyOperEnum.login) {
                                        if (errCode == 2030) {
                                            sendResult(mainActivityObj, DyOperEnum.login.getResult(), 102, null, "发送YZ到10690295553203");
                                        } else {
                                            sendResult(mainActivityObj, DyOperEnum.login.getResult(), 1, null, msg);
                                            clearExitApp(mainActivityObj);
                                        }
                                    } else if (mOperEnum == DyOperEnum.sendCode) {
                                        sendResult(mainActivityObj, DyOperEnum.sendCode.getResult(), 1, null, msg);
                                        clearExitApp(mainActivityObj);
                                    }
                                }
                            });
                        }
                    } else if (url.contains("/passport/mobile/login") && mOperEnum == DyOperEnum.login) {
                        JSONObject obj = new JSONObject(body);
                        String message = obj.optString("message");
                        if ("error".equals(message)) {
                            JSONObject data = obj.optJSONObject("data");
                            final int errCode = data.optInt("error_code");
                            final String msg = "error_code = " + errCode + ", description = " + data.optString("description");
                            mainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    TraceUtil.e("****** dy passport login failed ******");
                                    isPassLoginSuccess = false;
                                    if (errCode != 1039) {
                                        sendResult(mainActivityObj, DyOperEnum.login.getResult(), 1, null, msg);
                                        clearExitApp(mainActivityObj);
                                    }
                                }
                            });
                        }
                    }
                }
            }
        });
    }

    private void hookLogin(final ClassLoader classLoader, final Context context) {
        TraceUtil.e("hookLogin");
        IntentFilter filter = new IntentFilter();
        filter.addAction(DyOperEnum.loginVerify.getBroadcast());
        filter.addAction(DyOperEnum.smsLogin.getBroadcast());
        filter.addAction(DyOperEnum.smsReg.getBroadcast());
        filter.addAction(DyOperEnum.smsUpdatePassword.getBroadcast());
        filter.addAction(DyOperEnum.exit.getBroadcast());
        context.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(final Context context, final Intent intent) {
                String action = intent.getAction();
                TraceUtil.e("receive broadcast action " + action);
                mainHandler.removeCallbacksAndMessages(null);
                if (DyOperEnum.loginVerify.getBroadcast().equals(action)) {
                    mOperEnum = DyOperEnum.loginVerify;
                    mCode = intent.getStringExtra("code");
                    loginVerifyOper(dYLoginActivityObj, mCode);
                } else if (DyOperEnum.smsLogin.getBroadcast().equals(action)) {
                    mOperEnum = DyOperEnum.smsLogin;
                    mCode = intent.getStringExtra("code");
                    smsLoginOper(dYLoginActivityObj, mCode, "");
                } else if (DyOperEnum.smsReg.getBroadcast().equals(action)) {
                    mOperEnum = DyOperEnum.smsReg;
                    mCode = intent.getStringExtra("code");
                    mPass = intent.getStringExtra("password");
                    smsLoginOper(dYLoginActivityObj, mCode, mPass);
                } else if (DyOperEnum.smsUpdatePassword.getBroadcast().equals(action)) {
                    mOperEnum = DyOperEnum.smsUpdatePassword;
                    mCode = intent.getStringExtra("code");
                    smsConfirmUpdatePasswordOper(updatePasswordActivityObj, mCode);
                } else if (DyOperEnum.exit.getBroadcast().equals(action)) {
                    mainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            clearExitAppNoRes(context);
                        }
                    });
                }
            }
        }, filter);

        PhoneBeanCls = XposedHelpers.findClass("com.ss.android.ugc.aweme.account.login.e.a.b", classLoader);
        Class MainActivity = XposedHelpers.findClass("com.ss.android.ugc.aweme.main.MainActivity", classLoader);
        XposedHelpers.findAndHookMethod(MainActivity, "onCreate", Bundle.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("MainActivity onCreate");
                mainActivityObj = (Activity) param.thisObject;
                mPhone = (String) FilePersist.newInstance(HookMain.PACKAGE_ID_LITE).readData("phone", "18566506650");
                Intent getIntent = mainActivityObj.getIntent();
                if (getIntent != null) {
                    Bundle bundle = getIntent.getExtras();
                    TraceUtil.e("MainActivity bundle: " + (bundle != null ? bundle.toString() : "null"));
                    if (bundle != null) {
                        String cmd = bundle.getString("cmd");
                        String data = bundle.getString("data");
                        if (data == null) data = "";
                        JSONObject jsObj = new JSONObject();
                        try {
                            jsObj = new JSONObject(data);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                        if (!TextUtils.isEmpty(cmd)) {
                            if (DyOperEnum.login.toString().equals(cmd)) {
                                isPassLoginSuccess = true;
                                mOperEnum = DyOperEnum.login;
                                mPhone = jsObj.optString("phone");
                                mPass = jsObj.optString("password");
                            } else if (DyOperEnum.sendCode.toString().equals(cmd)) {
                                mOperEnum = DyOperEnum.sendCode;
                                mPhone = jsObj.optString("phone");
                            }
                        }
                    }
                }
            }
        });
        XposedHelpers.findAndHookMethod(MainActivity, "onResume", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("MainActivity onResume");
            }
        });
        XposedHelpers.findAndHookMethod(MainActivity, "onDestroy", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("MainActivity onDestroy");
                mainActivityObj = null;
            }
        });


        DYLoginActivityCls = XposedHelpers.findClass("com.ss.android.ugc.aweme.account.white.login.DYLoginActivity", classLoader);
        XposedHelpers.findAndHookMethod(DYLoginActivityCls, "onCreate", Bundle.class, new XC_MethodHook() {

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("DYLoginActivity onCreate");
                dYLoginActivityObj = (Activity) param.thisObject;
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mOperEnum == DyOperEnum.login) {
                            loginOper(dYLoginActivityObj, mPhone, mPass);
                        } else if (mOperEnum == DyOperEnum.sendCode) {
                            sendCodeOper(dYLoginActivityObj, mPhone);
                        }
                    }
                });
            }
        });
        XposedHelpers.findAndHookMethod(DYLoginActivityCls, "onResume", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("DYLoginActivity onResume");
            }
        });
        XposedHelpers.findAndHookMethod(DYLoginActivityCls, "onDestroy", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("DYLoginActivity onDestroy");
                dYLoginActivityObj = null;
            }
        });


        Class LoginB = XposedHelpers.findClass("com.ss.android.ugc.aweme.account.white.login.b", classLoader);
        Class CommonE = XposedHelpers.findClass("com.ss.android.ugc.aweme.account.white.common.e", classLoader);
        XposedHelpers.findAndHookMethod(LoginB, "a", CommonE, Bundle.class, boolean.class, new XC_MethodHook() {

            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);
                Bundle bundle = (Bundle) param.args[1];
                TraceUtil.e("LoginB bundle: " + bundle.toString());
            }
        });

        UpdatePasswordActivityCls = XposedHelpers.findClass("com.ss.android.ugc.aweme.account.ui.UpdatePasswordActivity", classLoader);
        XposedHelpers.findAndHookMethod(UpdatePasswordActivityCls, "onCreate", Bundle.class, new XC_MethodHook() {

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("UpdatePasswordActivity onCreate");
                updatePasswordActivityObj = (Activity) param.thisObject;
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mOperEnum == DyOperEnum.smsReg) {
                            updatePasswordOper(updatePasswordActivityObj, mPass);
                        }
                    }
                });
            }
        });
        XposedHelpers.findAndHookMethod(UpdatePasswordActivityCls, "onResume", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("UpdatePasswordActivity onResume");
            }
        });
        XposedHelpers.findAndHookMethod(UpdatePasswordActivityCls, "onDestroy", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                TraceUtil.e("UpdatePasswordActivity onDestroy");
                updatePasswordActivityObj = null;
            }
        });
    }

    private void loginPage() {
        if (mainActivityObj != null) {
            TraceUtil.e("****** dy passport login start ******");
            Bundle bundle = new Bundle();
            bundle.putBoolean("before_jump_finish_current", false);
            bundle.putInt("trigger", 0);
            bundle.putString("need_hide_login_way", "weixin|");
            bundle.putString("enter_from", "homepage_hot");
            bundle.putString("enter_method", "click_message");
            bundle.putInt("last_page_jump_here", 1);
            bundle.putInt("current_show_page", 2);
            bundle.putBoolean("can_back_to_last_page", false);
            bundle.putString("page_type", "normal_fenwei");
            bundle.putString("auth_app", "");
            bundle.putInt("login_last_platform_trust", 1);
            bundle.putString("login_title", "登录后即可查看消息");
            bundle.putInt("bundle_flow_type", 104);
            Activity act = mainActivityObj;
            Intent intent = new Intent();
            intent.setClass(act, DYLoginActivityCls);
            intent.putExtras(bundle);
            act.startActivity(intent);
        }
    }

    private void loginOper(final Activity activity, String phone, final String pass) {
        final Object phoneObj = XposedHelpers.newInstance(PhoneBeanCls);
        XposedHelpers.callMethod(phoneObj, "setNationalNumber", Long.valueOf(phone));

        final int phoneLayoutId = activity.getResources().getIdentifier("b9r", "id", activity.getPackageName());
        final int passId = activity.getResources().getIdentifier("b8r", "id", activity.getPackageName());
        final int checkId = activity.getResources().getIdentifier("bg4", "id", activity.getPackageName());
        final int buttonId = activity.getResources().getIdentifier("bzc", "id", activity.getPackageName());

        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                Object phoneLayout = activity.findViewById(phoneLayoutId);
                XposedHelpers.callMethod(phoneLayout, "setPhoneNumber", phoneObj);
                ((EditText) activity.findViewById(passId)).setText(pass);
                ((Checkable) activity.findViewById(checkId)).setChecked(true);
            }
        });
        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                (activity.findViewById(buttonId)).performClick();
            }
        }, 500);
        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (isPassLoginSuccess) {
                    TraceUtil.e("****** dy passport login end ******");
                    sendResult(mainActivityObj, DyOperEnum.login.getResult(), 1, null, "登录超时");
                    clearExitApp(activity);
                }
            }
        }, 10500);
    }

    private void loginVerifyOper(final Activity activity, final String code) {
        if (activity == null) {
            return;
        }

        TraceUtil.e("****** dy passport login verify start ******");
        final int titleId = activity.getResources().getIdentifier("title", "id", activity.getPackageName());
        if (titleId != 0 && activity.findViewById(titleId) != null) {
            TraceUtil.e("login verify 发送YZ到10690295553203");
            final int buttonId = activity.getResources().getIdentifier("a9e", "id", activity.getPackageName());
            mainHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    (activity.findViewById(buttonId)).performClick();
                }
            }, 500);
        } else {
            TraceUtil.e("login verify 请输入抖音发送的验证码");
            final int codeId = activity.getResources().getIdentifier("by4", "id", activity.getPackageName());
            final int buttonId = activity.getResources().getIdentifier("cu7", "id", activity.getPackageName());
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    EditText ed = activity.findViewById(codeId);
                    if (ed != null) {
                        ed.setText(code);
                    }
                }
            });
            mainHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    (activity.findViewById(buttonId)).performClick();
                }
            }, 500);
        }
        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                TraceUtil.e("****** dy passport login verify end ******");
                sendResult(mainActivityObj, DyOperEnum.loginVerify.getResult(), 1, null, "登录验证超时");
                clearExitApp(activity);
            }
        }, 40500);
    }

    private void sendCodePage() {
        if (mainActivityObj != null) {
            TraceUtil.e("****** dy passport send code start ******");
            Bundle bundle = new Bundle();
            bundle.putBoolean("before_jump_finish_current", true);
            bundle.putInt("trigger", 0);
            bundle.putString("need_hide_login_way", "weixin|");
            bundle.putString("enter_from", "homepage_hot");
            bundle.putString("enter_method", "click_message");
            bundle.putInt("last_page_jump_here", 0);
            bundle.putInt("current_show_page", 1);
            bundle.putBoolean("can_back_to_last_page", false);
            bundle.putString("page_type", "normal_fenwei");
            bundle.putString("auth_app", "");
            bundle.putInt("login_last_platform_trust", 0);
            bundle.putString("login_title", "登录后即可查看消息");
            bundle.putInt("bundle_flow_type", 103);
            Activity act = mainActivityObj;
            Intent intent = new Intent();
            intent.setClass(act, DYLoginActivityCls);
            intent.putExtras(bundle);
            act.startActivity(intent);
        }
    }

    private void sendCodeOper(final Activity activity, String phone) {
        final Object phoneObj = XposedHelpers.newInstance(PhoneBeanCls);
        XposedHelpers.callMethod(phoneObj, "setNationalNumber", Long.valueOf(phone));

        final int phoneLayoutId = activity.getResources().getIdentifier("b9r", "id", activity.getPackageName());
        final int buttonId = activity.getResources().getIdentifier("a89", "id", activity.getPackageName());

        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                Object phoneLayout = activity.findViewById(phoneLayoutId);
                XposedHelpers.callMethod(phoneLayout, "setPhoneNumber", phoneObj);
            }
        });

        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                (activity.findViewById(buttonId)).performClick();
            }
        }, 500);
    }

    /**
     * 如果password为空，进行简单的验证码登录
     * 如果password不为空，跳转到修改密码界面，修改密码
     *
     * @param activity
     * @param code
     * @param password
     */
    private void smsLoginOper(final Activity activity, final String code, final String password) {
        if (activity == null) {
            return;
        }

        TraceUtil.e("****** dy passport sms login start ******");
        final int codeId = activity.getResources().getIdentifier("by4", "id", activity.getPackageName());
        final int checkId = activity.getResources().getIdentifier("bg4", "id", activity.getPackageName());
        final int buttonId = activity.getResources().getIdentifier("bzc", "id", activity.getPackageName());

        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                EditText ed = (EditText) activity.findViewById(codeId);
                if (ed != null) {
                    ed.setText(code);
                    ((Checkable) activity.findViewById(checkId)).setChecked(true);
                }
            }
        });

        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                (activity.findViewById(buttonId)).performClick();
            }
        }, 500);

        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (TextUtils.isEmpty(password)) {
                    TraceUtil.e("****** dy passport sms login end ******");
                    sendResult(mainActivityObj, DyOperEnum.smsLogin.getResult(), 1, null, "登录超时");
                    clearExitApp(activity);
                } else {
                    updatePasswordPage();
                }
            }
        }, 10500);
    }

    private void updatePasswordPage() {
        if (mainActivityObj != null) {
            TraceUtil.e("****** dy update passport start ******");
            Activity act = mainActivityObj;
            Intent intent = new Intent();
            intent.setClass(act, UpdatePasswordActivityCls);
            act.startActivity(intent);
        }
    }

    private void updatePasswordOper(final Activity activity, final String pass) {
        if (activity == null) {
            return;
        }

        final int passId = activity.getResources().getIdentifier("zd", "id", activity.getPackageName());
        final int buttonId = activity.getResources().getIdentifier("lb", "id", activity.getPackageName());

        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                EditText ed = (EditText) activity.findViewById(passId);
                if (ed != null) {
                    ed.setText(pass);
                }
            }
        });

        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                (activity.findViewById(buttonId)).performClick();
                sendResult(mainActivityObj, DyOperEnum.smsReg.getResult(), 0, null, "");
                TraceUtil.e("****** dy update passport end ******");
            }
        }, 500);
    }

    private void smsConfirmUpdatePasswordOper(final Activity activity, final String code) {
        if (activity == null) {
            return;
        }

        TraceUtil.e("****** dy sms confirm update passport start ******");
        final int codeId = activity.getResources().getIdentifier("ze", "id", activity.getPackageName());
        final int buttonId = activity.getResources().getIdentifier("lb", "id", activity.getPackageName());

        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                EditText ed = (EditText) activity.findViewById(codeId);
                if (ed != null) {
                    ed.setText(code);
                }
            }
        });

        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                (activity.findViewById(buttonId)).performClick();
            }
        }, 500);

        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                TraceUtil.e("****** dy sms confirm update passport end ******");
                sendResult(mainActivityObj, DyOperEnum.smsUpdatePassword.getResult(), 0, mLoginInfo, "");
                clearExitApp(activity);
            }
        }, 3500);
    }

    private void clearApp() {
        TraceUtil.e("****** dy clear app start ******");
        String baseInner = "/data/user/0/" + HookMain.PACKAGE_ID_LITE + "/";
        String baseExternal = "/storage/emulated/0/Android/data/" + HookMain.PACKAGE_ID_LITE + "/";

        // 删除SharedPreferences 账户信息
        File file = new File(baseInner + "shared_prefs/aweme_user.xml");
        FileUtil.deleteFile(file);
        // 删除SharedPreferences cdid信息
        file = new File(baseInner + "shared_prefs/com.ss.android.deviceregister.utils.Cdid.xml");
        FileUtil.deleteFile(file);
        // 删除SharedPreferences udid、udid_list、openudid、clientudid、serial_number信息
        file = new File(baseInner + "shared_prefs/snssdk_openudid.xml");
        FileUtil.deleteFile(file);
        // 删除SharedPreferences device_id信息
        file = new File(baseInner + "shared_prefs/applog_stats.xml");
        FileUtil.deleteFile(file);
        // 删除SharedPreferences cookies缓存
        file = new File(baseInner + "shared_prefs/ttnetCookieStore.xml");
        FileUtil.deleteFile(file);

        // 删除Files 下的device信息
        file = new File(baseInner + "files/keva/repo/");
        FileUtil.deleteDirWithFile(file);
        TraceUtil.e("keva/repo 文件夹已清空！");
        // 删除APP_WEBVIEW下cookies缓存
        file = new File(baseInner + "app_webview/Cookies");
        FileUtil.deleteFile(file);

        // 删除contentProvider device_id信息
        file = new File(baseExternal + "bytedance/device_parameters.dat");
        FileUtil.deleteFile(file);

        // 删除com.snssdk.api device_id信息
        file = new File(baseExternal + "bytedance/device_parameters.dat");
        String snssdkPath = file.getAbsolutePath().replace(HookMain.PACKAGE_ID_LITE, "com.snssdk.api");
        file = new File(snssdkPath);
        FileUtil.deleteFile(file);

        // 删除sdcard device_id信息
        file = new File("/storage/emulated/0/bytedance/device_parameters.dat");
        FileUtil.deleteFile(file);

        TraceUtil.e("****** dy clear app end ******");
    }

    private void exitApp(Context context) {
        TraceUtil.e("****** dy exit app start ******");

        // 退出app
        // 需要禁止app后台运行，否则退出app后会自动重启
        ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.AppTask> appTaskList = activityManager.getAppTasks();
        for (ActivityManager.AppTask appTask : appTaskList) {
            appTask.finishAndRemoveTask();
        }
        TraceUtil.e("****** dy exit app end ******");
        System.exit(0);
    }

    private void clearExitApp(Context context) {
        if (context == null) {
            return;
        }

        clearApp();
        // 发送关闭app结果
        mOperEnum = DyOperEnum.exit;
        sendResult(context, DyOperEnum.exit.getResult(), 0, null, "");
        exitApp(context);
    }

    private void clearExitAppNoRes(Context context) {
        if (context == null) {
            return;
        }

        clearApp();
        exitApp(context);
    }

    private void sendResult(Context context, String action, int code, JSONObject data, String msg) {
        if (context != null && mOperEnum != DyOperEnum.unknown) {
            JSONObject obj = new JSONObjectPack()
                    .putValue("code", code)
                    .putValue("data", (data == null ? new JSONObject() : data))
                    .putValue("msg", msg)
                    .getJSONObject();
            Intent intent = new Intent(action);
            intent.putExtra("data", obj.toString());
            context.sendBroadcast(intent);
        }
        mOperEnum = DyOperEnum.unknown;
    }

}


